Data Fetching and Revalidation
Data inside a route can be fetched using two functions:
Client Fetcher - Executes on client side navigation or absence of server fetcher.
Server Fetcher - Executes on when client requests server for a page during first paint (SSR).
const HomePage = ()=><div>HomePage</div>
//Fetcher functions returning Promise
HomePage.clientFetcher = (routerProps,fetcherArgs) => { return new Promise()}
HomePage.serverFetcher = (serverRouterProps,fetcherArgs) => { return new Promise()}
Both clientFetcher
and serverFetcher
functions should either return a promise or should be async functions.
Data fetched through clientFetcher
or serverFetcher
will not be re-fetched once it is fetched unless refetch
or clear
are used.
We'll talk about revalidation in detail in further sections.
Client Fetcher
clientFetcher
will be called during client side navigation, when navigating through <Link/>
or <Navigate>
components or by using hooks like useNavigate
provided by router.
clientFetcher
will not be executed on app load on the client in caseserverFetcher
was executed on the server.
Client side navigation in @tata1mg/router
is based on react-router-v6.
Home.clientFetcher = async ({route,location,params,searchParams,navigate},{store}) => {
const res = await fetch("some_url");
const json = await res.json();
return json;
};
Type definition
/**
* @typedef FetcherParams
* @property {any} route Route object defined in routes array
* @property {import("react-router-dom").Location} location the current location object, which represents the current URL in web browsers.
* @property {import("react-router-dom").Params} params object of key/value pairs of the dynamic params from the current URL that were matched by the route path.
* @property {URLSearchParams} searchParams search parameters via URLSearchParams interface.
* @property {import("react-router-dom").Navigate} navigate function to navigate to other pages based on response.
*/
/**
* @description Fetcher function to fetch page data returns a promise which resolve or reject to set data or error in RouterContext
* @param {FetcherParams} fetcherParams
* @param {any} fetcherArgs anything passed in fetcherArgs prop of RouterProvider
* @returns Promise<any>
*/
export const clientFetcher = ({ route, location, params, searchParams, navigate }, fetcherArgs) => {
return new Promise()
}
Server Fetcher
serverFetcher
will be called during the first fold request or when navigation is done by window.location.href
or similar methods. It will only be called on the server and will not be included in the client bundle, so it is safe to use server only secrets in this function.
Home.serverFunction = async ({route, location, params, searchParams, navigate},{store}) => {
const res = await fetch("some_url");
const json = await res.json();
return json;
};
Type Definition
/**
* @typedef FetcherParams
* @property {any} route Route object defined in routes array
* @property {import("react-router-dom").Location} location the current location object, which represents the current URL in web browsers.
* @property {import("react-router-dom").Params} params object of key/value pairs of the dynamic params from the current URL that were matched by the route path.
* @property {URLSearchParams} searchParams search parameters via URLSearchParams interface.
* @property {import("react-router-dom").Navigate} navigate function to navigate to other pages based on response.
*/
/**
* @description Fetcher function to fetch page data returns a promise which resolve or reject to set data or error in RouterContext
* @param {FetcherParams} fetcherParams
* @param {any} fetcherArgs anything passed in fetcherArgs prop of RouterProvider
* @returns Promise<any>
*/
export const serverFetcher = ({ route, location, params, searchParams, navigate }, fetcherArgs) => {
return new Promise()
}
Accessing data from router
useCurrentRouteData
hook
useCurrentRouteData
hook from @tata1mg/router
returns the current router context object with data
, error
, isFetching
, isFetched
, refetch
and clear
properties.
Details of each property are provided below :
Key | State |
---|---|
isFetching | Data fetching is in progress |
isFetched | Fetcher function is resolved/rejected |
error | Error object thrown by clientFetcher |
data | Data object returned by clientFetcher |
refetch | A function that can be called to manually trigger clientFetcher of the route. |
clear | Function to clear route cache for a particular route |
Example :
import { useCurrentRouteData } from "@tata1mg/router"
const Home = () => {
const { isFetching, isFetched, error, data, refetch, clear } = useCurrentRouteData()
}
Home.clientFetcher = async () => {
return {status:200}
}
useRouterData
hook
The useRouterData hook returns a router context object with data of all the fetchers in the current route tree.
// route: /a/b
import { useRouterData } from '@tata1mg/router';
const routerData = useRouterData();
//Supposed you have /a route and /b as child route and attached fetchers to all the routes following is going to be the structure of routerData
{
"/a/b":{ isFetching , isFetched , error , data }, "index/a":{ isFetching , isFetched , error , data }
}
Revalidating data
For data revalidation, refetch
and clear
functions are used.
They are accessed through the useCurrentRouteData
hook
Refetch
refetch
executes the client loader. A custom argument can be passed while calling it through refetch in client loader to handle use cases where the fetch function needs to access the application state like for pagination, infinite scroll, etc.
The custom argument passed by refetch will be available as the third argument of in clientFetcher
Example :
const Home = () => {
...
useEffect(()=>{
refetch({pageNo})
},[pageNo])
}
Home.clientFetcher = async ({},{},{pageNo}) => {
const res = await fetch(`some_url/${pageNo}`)
const json = await res.json()
return json
}
Clear
The clear
function clears the data for the particular route from where it is called.
Example :
const Home = () => {
...
useEffect(()=>{
clear()
},[pathname])
//will clear data for this particular route on navigation
}